#include <stdio.h>
#include "AppDX10.h"

extern CApplication *g_pApp;

ID3D10Device *CAppDX10::GetD3DDevice( )
{
    return ((CAppDX10*)g_pApp)->m_pD3DDevice;
}

CAppDX10::CAppDX10( int a_iWidth, int a_iHeight )
    :CApplication(a_iWidth, a_iHeight)
{
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof(sd) );
    sd.BufferCount = 1;
    sd.BufferDesc.Width = a_iWidth;
    sd.BufferDesc.Height = a_iHeight;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = m_hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;

    /*if( FAILED( D3D10CreateDeviceAndSwapChain( NULL, D3D10_DRIVER_TYPE_REFERENCE, NULL,
        0, D3D10_SDK_VERSION, &sd, &m_pSwapChain, &m_pD3DDevice ) ) )
    {
        return FALSE;
    }*/
    //HRESULT hr;
    D3D10CreateDeviceAndSwapChain( NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL,
        0, D3D10_SDK_VERSION, &sd, &m_pSwapChain, &m_pD3DDevice );
    ID3D10Texture2D *pBackBuffer;
    m_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID*)&pBackBuffer );
    m_pD3DDevice->CreateRenderTargetView(pBackBuffer, NULL, &m_pBackBufferRTV);
    pBackBuffer->Release();
    m_pD3DDevice->OMSetRenderTargets(1, &m_pBackBufferRTV, NULL);
    D3D10_VIEWPORT vp;
    vp.Width    = a_iWidth;
    vp.Height   = a_iHeight;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    m_pD3DDevice->RSSetViewports( 1, &vp );
    D3DX10CreateFontA(m_pD3DDevice, 24, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, 
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,  
        DEFAULT_PITCH, LPCSTR("Times New Roman"), &m_pFont); 
}

void CAppDX10::RenderText(RECT rect, char *fmt, ...)
{
    char        text[256];                              
    va_list     ap; 
    va_start(ap, fmt);                                  
    vsprintf_s(text, 256, fmt, ap);                        
    va_end(ap);
    m_pFont->DrawTextA(NULL, text, -1, &rect, DT_LEFT, 
        D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
}

void CAppDX10::RenderScene( )
{
    float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; // RGBA
    m_pD3DDevice->ClearRenderTargetView( m_pBackBufferRTV, ClearColor );    
    CApplication::RenderScene( );
    RECT rcFpsText;
    DWORD elapsed = 0;
    static DWORD FpsCount = 0;
    static DWORD FrameNum = 0;
    static DWORD FpsTimeCount = 0;
    static DWORD curtime = GetTickCount();
    rcFpsText.left = 0;
    rcFpsText.top = 10;
    rcFpsText.right = 200;
    rcFpsText.bottom = 100;
    elapsed = GetTickCount() - curtime;
    FpsTimeCount += elapsed;
    FrameNum++;
    curtime = GetTickCount();
    if (FpsTimeCount > 1000)
    {
        FpsTimeCount = 0;
        FpsCount = FrameNum;
        FrameNum = 0;
    }
    RenderText(rcFpsText, "DX10 Renderer\nFps = %d\n", FpsCount);    
    m_pSwapChain->Present( 0, 0 );
}

CAppDX10::~CAppDX10( )
{
    m_pSwapChain->Release();
    m_pD3DDevice->Release();
    m_pBackBufferRTV->Release();
    m_pFont->Release();
    //m_pRS->Release();
}